import {
  clearEmptyLinkageItems, getNoValLinkageItem,
} from '@/components/common/advanced-linkage/advanced-linkage-util.js';
import { getCommonParamsUpdatedEvtKeys } from '@/components/multi-params/multi-params-util.js';
import storage from '@/storage/storage.js';
import { getVarChildVal, objDiff, objHas } from '@/utils/util-common.js';
import { isEqual, uniqWith } from 'lodash';

// 行业组件跟可视化组件同时使用时，xvue会注册两次可视化状态库，会导致某些共享状态失效，通过以下代码修复
const mergeStore = store => {
  let newStore = store;
  if (!window.visualComp) {
    window.visualComp = {};
  }
  if (window.visualComp.VisualComponentsModule) {
    newStore = window.visualComp.VisualComponentsModule;
    const arr = ['state', 'mutations', 'actions', 'getters'];
    arr.forEach(n => {
      if (!store[n]) {
        return false;
      }
      Object.entries(store[n]).map(([key, val]) => {
        if (newStore[n][key] === null || newStore[n][key] === undefined) {
          newStore[n][key] = val;
        }
      });
      return true;
    });
  }
  newStore.isCompatible = true; // 其他vapp注册时，在xvue判断如果有这个参数，则合并store，否则跳过，防止替换可视化的store
  window.visualComp.VisualComponentsModule = newStore;
  return newStore;
};

const store = {
  state: {
    pageId: '',
    emitComponentStatusObj: {},
    allComponentsReady: false, // 是否所有组件第一次已加载完成，准备就绪

    // 公共参数
    commonParams: {}, // 公共参数
    commonParamsDiff: [{}, {}], // 公共参数改变前后对比，[{后减前}, {前减后}]，用于区分哪些组件需要重新请求
    commonParamsUpdatedEvtKeys: [], // 需要重新触发事件联动的事件

    visualParamsOutObj: {}, // 本地联动调试用
    curEvtEmitObj: {}, // 当前普通事件提交给xvue的outObj对象，可用于子组件监听
    componentsHistory: {}, // 组件状态历史记录
    componentsData: {},
    componentsRealTimeApiData: {}, // 属性配置面板realTimeApis
    panelApiData: [], // 数据配置面板选择api时触发请求接收的数据，用于下拉列表
    panelApiTableData: [],
    panelApiChartData: [], // 左表右图结构的数据配置面板选择api时触发请求接收的数据，用于下拉列表
    panelApiDatas: {}, // panelApiData的升级版，可以容纳多个组件数据，用于父子嵌套组件，如进度图的表格
    winContainers: [], // 弹窗组件
    curWinContainerWid: '', // 当前打开的弹窗组件id

    // 属性，数据，事件配置临时存储，解决跨面板数据访问
    panelConfig: {
      siteId: '',
      widgetInstanceId: '',
      property: {},
      data: {
        tableData: [],
      },
      events: {},
    },
    panelConfigs: {},
    cameraConfigs: {}, // 海康视频组件存储监控点编号

    // echart共享操作
    echartActions: {
      outWid: '', // 发出事件的组件id
      dataZoomX: {},
      legend: {},
    },
    saveAllDataProcess: {

      // 组件配置保存过程
      isChecking: false,
      errors: [],
    },
    asTooltips: [], // 整个组件作为tooltip配置
    asTooltipUsers: [], // 组件tooltip使用者
    tooltipOnWid: '', // 当前tooltip展示所在组件的组件id

    // 屏幕分辨率flex布局等比缩放使用
    rateW: 1,
    rateH: 1,
    rate: 1,
    resizeCount: 0,

    needClearOutEvent: {}, // 组件销毁时，将组件的发出事件清除

    // 高级事件联动
    advancedLinkage: {
      sentByWid: null,
      sentLinkageDatas: null,
      linkageDatas: [],
    },

    // 当前属性配置面板颜色主题值
    formComponentStyle: 'light',

    // 组件之间排斥互动，如一个组件选中，则另外一个组件取消选中
    repulsion: {},
  },
  getters: {
    emitComponentStatus: state => {
      if (!state.pageId) {
        return false;
      }
      let canEmit = true; // 组件能否发出事件
      const { pageId } = state;

      const pageComponent = state.emitComponentStatusObj[pageId];
      for (const key in pageComponent) {
        // 存在有异步没加载完
        if (pageComponent[key]) {
          canEmit = false;
        }
      }
      return canEmit;
    },
  },
  mutations: {
    setComponentStatus(state, { pageId, widgetInstanceId, hasAsync }) {
      state.pageId = pageId;
      if (!state.emitComponentStatusObj[pageId]) {
        state.emitComponentStatusObj[pageId] = {};
      }
      state.emitComponentStatusObj[pageId][widgetInstanceId] = hasAsync;
    },
    deleteComponentStatus(state, { pageId, widgetInstanceId }) {
      const statusObj = state.emitComponentStatusObj[pageId];
      if (!statusObj) {
        return;
      }
      if (objHas(statusObj, widgetInstanceId)) {
        delete statusObj[widgetInstanceId];
      }
    },
    setPageId(state, pageId) {
      state.pageId = pageId;
    },

    // 设置公共参数
    setCommonParams(state, { widgetInstanceId, evtKey, params }) {
      const _old = JSON.parse(JSON.stringify(state.commonParams));
      state.commonParams[widgetInstanceId] = { evtKey, params };
      const _new = state.commonParams;
      storage.setItem('commonParams', JSON.stringify(_new));
      state.commonParamsDiff = [objDiff(_new, _old), objDiff(_old, _new)];
      const evtKeys = getCommonParamsUpdatedEvtKeys();
      state.commonParamsUpdatedEvtKeys = evtKeys;
    },

    // 删除公共参数
    delCommonParams(state, widgetInstanceId) {
      const _old = JSON.parse(JSON.stringify(state.commonParams));
      delete state.commonParams[widgetInstanceId];
      const _new = state.commonParams;
      storage.setItem('commonParams', JSON.stringify(_new));
      state.commonParamsDiff = [objDiff(_new, _old), objDiff(_old, _new)];
      const evtKeys = getCommonParamsUpdatedEvtKeys();
      state.commonParamsUpdatedEvtKeys = evtKeys;
    },

    setComponentsData(state, { widgetInstanceId, componentData }) {
      if (!state.componentsData[widgetInstanceId]) {
        state.componentsData[widgetInstanceId] = {};
      }
      state.componentsData[widgetInstanceId] = componentData;
    },
    deleteComponentsData(state, widgetInstanceId) {
      delete state.componentsData[widgetInstanceId];
    },

    setRealTimeApiData(state, { widgetInstanceId, componentData }) {
      state.componentsRealTimeApiData[widgetInstanceId] = componentData;
    },

    // 简化mutation设值方法
    setState(state, payload) {
      for (const [key, value] of Object.entries(payload)) {
        if (objHas(state, key)) {
          state[key] = value;
        }
      }
    },

    // 保存组件配置时，录入报错信息
    setSaveAllDataErr(state, err) {
      const { errors } = state.saveAllDataProcess;
      errors.push(err);
    },

    /* ------------ 组件级tooltip ----------- */
    setAsTooltip(state, item = {}) {
      const { asTooltips } = state;
      for (let i = 0; i < asTooltips.length; i++) {
        const n = asTooltips[i];
        if (n.wid === item.wid) {
          state.asTooltips.splice(i, 1);
        }
      }
      if (item.asTooltipKey) {
        state.asTooltips.push(item);
      }
    },
    clearAsTooltip(state, wid) {
      const { asTooltips } = state;
      for (let i = 0; i < asTooltips.length; i++) {
        const n = asTooltips[i];
        if (n.wid === wid) {
          state.asTooltips.splice(i, 1);
        }
      }
    },
    setAsTooltipUser(state, item = {}) {
      const { asTooltipUsers } = state;
      for (let i = 0; i < asTooltipUsers.length; i++) {
        const n = asTooltipUsers[i];
        if (n.wid === item.wid && n.asTooltipKey === item.asTooltipKey) {
          state.asTooltipUsers.splice(i, 1);
        }
      }
      if (item.wid && item.asTooltipKey) {
        state.asTooltipUsers.push(item);
      }
    },
    clearAsTooltipUser(state, wid) {
      const { asTooltipUsers } = state;
      for (let i = 0; i < asTooltipUsers.length; i++) {
        const n = asTooltipUsers[i];
        if (n.wid === wid) {
          state.asTooltipUsers.splice(i, 1);
        }
      }
    },
    setAsTooltipUserVars(state, item = {}) {
      const { asTooltipUsers } = state;
      asTooltipUsers.forEach(n => {
        n.isHovering = n.wid === item.wid;
      });
      const users = asTooltipUsers.filter(n => n.wid === item.wid);
      const vars = {};
      users.forEach(user => {
        user.correlatedData.forEach(n => {
          vars[n.priMapKey] = getVarChildVal(item.vars, n.priKey);
        });
        user.vars = vars;
      });
      state.asTooltipUsers = asTooltipUsers;
    },

    /* ------------ 高级事件联动 ----------- */
    setAdvancedLinkage(state, _linkageDatas) {
      if (_linkageDatas.length) {
        let { linkageDatas } = state.advancedLinkage;
        const { wid } = _linkageDatas[0];

        // 去除条件，跳转设置，事件名相同项目
        const _linkageDatasNoVal = _linkageDatas.map(n => getNoValLinkageItem(n));
        linkageDatas = linkageDatas.filter(n => {
          const nNoVal = getNoValLinkageItem(n);
          const hasSame = _linkageDatasNoVal.some(n1 => isEqual(nNoVal, n1));
          return !hasSame;
        });

        linkageDatas = [...linkageDatas, ..._linkageDatas];

        state.advancedLinkage.sentByWid = wid;
        state.advancedLinkage.sentLinkageDatas = _linkageDatas; // 发送者联动事件
        state.advancedLinkage.linkageDatas = uniqWith(linkageDatas, isEqual); // 全量联动事件
      }
    },

    // 删除单个参数
    delAdvancedLinkageParam(state, param) {
      let { linkageDatas } = state.advancedLinkage;
      linkageDatas = JSON.parse(JSON.stringify(linkageDatas));
      linkageDatas.forEach(n => {
        n.events.forEach(ev => {
          const item = ev.params.find(p => (
              n.wid === param.wid &&
              ev.evtKey === param.evtKey &&
              p.evtParameterKey === param.evtParameterKey &&
              isEqual(p.evtParameterVal, param.evtParameterVal)
          ));

          if (item) {
            const index = ev.params.indexOf(item);
            if (index > -1) {
              ev.params.splice(index, 1);
            }
          }
        });
      });

      linkageDatas = clearEmptyLinkageItems(linkageDatas);
      state.advancedLinkage.linkageDatas = linkageDatas;
      state.advancedLinkage.sentByWid = param.wid;
      state.advancedLinkage.sentLinkageDatas = null;
    },

    // 删除跟传入事件key相同的事件
    delAdvancedLinkageEvents(state, events) {
      let hasEvt = false;
      const evtKeys = events.map(n => n.evtKey);
      let { linkageDatas } = state.advancedLinkage;
      linkageDatas = JSON.parse(JSON.stringify(linkageDatas));
      linkageDatas.forEach(n => {
        n.events = n.events.filter(ev => {
          const _hasEvt = evtKeys.includes(ev.evtKey);
          hasEvt = _hasEvt || hasEvt;
          return !_hasEvt;
        });
      });
      if (hasEvt) {
        state.advancedLinkage.linkageDatas = uniqWith(linkageDatas, isEqual);
      }
    },

    // 根据组件id清除联动，用于点击组件空白处
    delAdvancedLinkageByWid(state, wid) {
      const { linkageDatas } = state.advancedLinkage;
      const _linkageDatas = linkageDatas.filter(n => n.wid !== wid);
      if (_linkageDatas.length !== linkageDatas.length) {
        state.advancedLinkage.sentByWid = wid;
        state.advancedLinkage.linkageDatas = _linkageDatas;
      }
    },

    // 清空高级事件联动
    clearAdvancedLinkage(state) {
      state.advancedLinkage = {
        sentByWid: null,
        sentLinkageDatas: null,
        linkageDatas: [],
      };
    },

    setRepulsion(state, { groupKey, wid }) {
      if (groupKey) {
        state.repulsion[groupKey] = wid;
        state.repulsion = { ...state.repulsion };
      }
    },
    setPanelConfig(state, panelConfig) {
      const wid = panelConfig.widgetInstanceId;
      state.panelConfig = panelConfig; // 兼容原来的变量
      state.panelConfigs[wid] = panelConfig;
      state.panelConfigs = { ...state.panelConfigs };
    },
    delPanelConfig(state, wid) {
      delete state.panelConfigs[wid];
    },
    setPanelApiData(state, { wid, panelApiData }) {
      state.panelApiData = panelApiData; // 兼容原来的变量
      state.panelApiDatas[wid] = panelApiData;
      state.panelApiDatas = { ...state.panelApiDatas };
    },
    delPanelApiData(state, wid) {
      state.panelApiData = [];
      delete state.panelApiDatas[wid];
    },

  },
};

export default mergeStore(store);
